// MainMenu.cs
//

using System;
using System.Collections.Generic;
using jQueryApi;
using System.Html;

// TODO:select all on save

namespace TuringMachine
{
    public delegate void LevelClickedHandler(string levelKey);
    public class MainMenu : MessageBoxBase
    {
        ListView m_ListViewChallenges;
        TMButton m_btnPlay;
        public event LevelClickedHandler OnLevelClicked;
        private string m_level;
        private Label m_CreditsText;
        private Label m_title;
        private Label m_invitation;
        private static int m_ScrollPos = 0;
        private static int m_iPositionSelected = -1;
        private Div m_selectAfterShown = null;
        private const string m_subtitle = "<p style='margin-top:-30px;color:#";
        private const string m_subtitle2 = "'>A <I>Turing machine</I> game</p>";
        private bool m_bScrolling = false;

        public MainMenu(jQueryObject parent, int iCredits, List<Challenge> lChallenges, List<string> lCompletedChallenges) :
            base(parent)
        {
            
            m_msgBox.CSS("width", "900px");
            m_okButton.pText = "Shop";
            m_cancelButton.pText = "Tutorial";
            m_ListViewChallenges = new ListView(m_msgBox, "lv");
            m_ListViewChallenges.pObject.CSS("width", (m_msgBox.GetWidth() - 40) + "px");
            m_ListViewChallenges.pObject.CSS("height", "400px");
            m_ListViewChallenges.pPosX = 20;
            m_ListViewChallenges.pPosY = 150;
            m_ListViewChallenges.pDefaultHeight = 90;
            m_ListViewChallenges.OnItemClicked += new ItemEventHandler(m_ListViewChallenges_OnItemClicked);

            m_msgBox.MouseDown(delegate
            {
                m_bScrolling = true;
            });

            m_msgBox.MouseUp(delegate
            {
                m_bScrolling = false;
            });
            m_btnPlay = new TMButton(m_ListViewChallenges.pObject, "Try!", false);
            m_btnPlay.pVisible = false;
            m_btnPlay.OnClick += new ButtonEventHandler(m_btnPlay_OnClick);
            m_btnPlay.pObject.MouseDown(delegate
            {
                m_title = null;
            });

            int idx = 0;
            m_selectAfterShown = null;
            foreach (Challenge challenge in lChallenges)
            {
                Div item = new Div(m_ListViewChallenges.pObject, "item");

                item.pObject.Append("<b><u><p style='float:left;margin-top:0px;margin-bottom:2px'>" + challenge.pName +
                      "</p></u><p style='float:right;color:Red;margin-top:0px;margin-bottom:2px'>Credits: " + challenge.pCredits +
                      "</p></u></b><p style='clear:both;text-align:left;'>" +
                      challenge.pDescription +
                      "</p>");
                item.pObject.Data("key", challenge.pName);
                item.pObject.Data("index", idx);
                m_ListViewChallenges.AddItem(item);

                if (lCompletedChallenges.Contains(challenge.pName))
                {
                    StateCell cell = new StateCell(m_ListViewChallenges.pObject);
                    cell.pObject.CSS("position", "relative");
                    cell.pObject.CSS("float", "right");
                    cell.pObject.CSS("margin-bottom", "-32px");
                    cell.pPosX = -9;
                    cell.pPosY = -36;
                    cell.pOperation = StateBoard.OP_ACCEPT;
                }
                if (idx == m_iPositionSelected)
                    m_selectAfterShown = item;
                idx++;
            }

            m_title = new Label(m_msgBox, "title");
            m_title.pObject.CSS("position", "static");
            m_title.pHtml = "<H1>Gachimator</H1>";
            m_title.pObject.CSS("width", "200px");
            m_title.pObject.CSS("height", "60px");
            Window.SetTimeout(AnimateTitle, 1000);

            m_invitation = new Label(m_msgBox, "invite");
            m_invitation.pObject.CSS("position", "static");
            m_invitation.pObject.CSS("text-align", "left");
            m_invitation.pObject.CSS("display", "block");
            m_invitation.pObject.CSS("margin-left", "20px");
            m_invitation.pHtml = "<br/>Please select the level you want to try next. If you got any credits " +
               "you can buy some upgrades in the shop. Check the tutorial for a quick introduction into the game.";

            m_CreditsText = new Label(m_msgBox, "creditsText");
            m_CreditsText.pObject.CSS("position", "absolute");
            m_CreditsText.pText = "Your current credits :" + iCredits.ToString();

            m_lCompletedChallenges = lCompletedChallenges;
        }


        int m_iHighlight = 0;
        Color m_cHighlight = new Color(255, 128, 32);
        Color m_cSubtitle = new Color(32, 128, 32);
        Color m_cRest = new Color(255, 32, 64);
        private List<string> m_lCompletedChallenges;

        void AnimateTitle()
        {
            if (m_title != null)
            {
                if (!m_bScrolling)
                {
                    string title = "Gachimator";
                    string html = "<H1 style='color:#" + m_cRest.ToString() + "'>";
                    for (int i = 0; i < title.Length; i++)
                    {
                        if (i == m_iHighlight)
                            html += "<span style='color:#" + m_cHighlight.ToString() + "'>";
                        html += title.Substr(i, 1);
                        if (i == m_iHighlight)
                            html += "</span>";
                    }
                    m_iHighlight = (m_iHighlight + 1) % title.Length;
                    html += "</H1>" + m_subtitle + m_cSubtitle.ToString() + m_subtitle2;
                    m_cHighlight.Gradient(0x030000);
                    m_cRest.Gradient(0x300);
                    m_cSubtitle.Gradient(0x30000);
                    m_title.pHtml = html;

                }
                Window.SetTimeout(AnimateTitle, 100);
            }
        }

        public override void OnShown()
        {
            base.OnShown();

        }

        protected override void CancelButton_Click(TMButton sender)
        {
            m_title = null;
            base.CancelButton_Click(sender);
        }

        protected override void OkButton_Click(TMButton sender)
        {
            m_title = null;
            base.OkButton_Click(sender);
        }

        void m_btnPlay_OnClick(TMButton sender)
        {
            if (OnLevelClicked != null)
            {
                m_title = null;
                m_ScrollPos = m_ListViewChallenges.pObject.GetScrollTop();
                Close(CloseResult.none);
                OnLevelClicked(m_level);
            }
        }

        void m_ListViewChallenges_OnItemClicked(Div sender, EventArgs ev)
        {
            m_btnPlay.pPosX = sender.pObject.GetWidth() - 30 - m_btnPlay.pObject.GetWidth();
            m_btnPlay.pPosY = sender.pPosY + m_ListViewChallenges.pObject.GetScrollTop() +
               sender.pObject.GetHeight() - m_btnPlay.pObject.GetHeight() + 8;
            m_btnPlay.pVisible = true;
            m_level = (string)sender.pObject.GetDataValue("key");
            if (m_lCompletedChallenges.Contains(m_level))
                m_btnPlay.pText = "Retry...";
            else
                m_btnPlay.pText = "Try!";
            m_iPositionSelected = (int)sender.pObject.GetDataValue("index");

        }

        protected override void PlaceElements()
        {
            m_msgBox.CSS("height", "700px");
            m_CreditsText.pPosY = m_msgBox.GetHeight() - 100;
            m_CreditsText.pPosX = (m_msgBox.GetWidth() - m_CreditsText.pObject.GetWidth()) / 2;
            m_ListViewChallenges.pObject.ScrollTop(m_ScrollPos);
            if (m_selectAfterShown != null)
                m_ListViewChallenges.SelectItem(m_selectAfterShown);
        }

    }


    public class Color
    {
        public int r;
        public int g;
        public int b;

        int dir_r;
        int dir_g;
        int dir_b;

        public Color(int r, int g, int b)
        {
            this.r = r;
            this.g = g;
            this.b = b;
            dir_r = dir_g = dir_b = 1;
        }

        public override string ToString()
        {
            return r.ToString(16).PadLeft(2, '0') +
               g.ToString(16).PadLeft(2, '0') +
               b.ToString(16).PadLeft(2, '0');
        }

        internal void Gradient(int val)
        {
            int incR = val & 0xFF;
            int incG = (val >> 8) & 0xFF;
            int incB = (val >> 16) & 0xFF;
            this.r = (this.r + incR * dir_r);
            this.g = (this.g + incG * dir_g);
            this.b = (this.b + incB * dir_b);

            Clamp(incR, incG, incB);
            Clamp(incR, incG, incB);
        }

        private void Clamp(int incR, int incG, int incB)
        {
            if (this.r < 0)
            {
                this.r = 0; dir_r = 1;
                this.g += incR * dir_g;
            }
            if (this.r > 255)
            {
                this.r = 255; dir_r = -1;
                this.g += incR * dir_g;
            }
            if (this.g < 0)
            {
                this.g = 0; dir_g = 1;
                this.b += incG * dir_b;
            }
            if (this.g > 255)
            {
                this.g = 255; dir_g = -1;
                this.b += incG * dir_b;
            }
            if (this.b < 0)
            {
                this.b = 0; dir_b = 1;
                this.r += incB * dir_r;
            }
            if (this.b > 255)
            {
                this.b = 255; dir_b = -1;
                this.r += incB * dir_r;
            }
        }
    }
}
